<!DOCTYPE HTML>
<html lang="en-US">
<head>
	<meta charset="UTF-8">
	<title>.require</title>

	<script type="text/javascript" src="../../dances.amd.js" data-require-boot="js/boot.js"></script>
	<!--<script type="text/javascript" src="../../release/dances.amd_2.0.js" data-require-boot="js/boot.js"></script>-->

	<link rel="stylesheet" type="text/css" href="../../../_helper/jasmine/lib/1.3.1/jasmine.css" media="all">
	<script type="text/javascript" src="../../../_helper/jasmine/lib/1.3.1/jasmine.js"></script>
	<script type="text/javascript" src="../../../_helper/jasmine/lib/1.3.1/jasmine-html.js"></script>

	<script type="text/javascript">
		(function(){
			var jasmineEnv = jasmine.getEnv();
			jasmineEnv.updateInterval = 1000;

			var htmlReporter = new jasmine.HtmlReporter();
//			var htmlReporter = new jasmine.TrivialReporter();

			jasmineEnv.addReporter(htmlReporter);

			jasmineEnv.specFilter = function(spec){
				return htmlReporter.specFilter(spec);
			};

			var currentWindowOnload = window.onload;

/*
			window.onload = function(){
				if(currentWindowOnload){
					currentWindowOnload();
				}
				execJasmine();
			};
*/

			window.execJasmine = function(){
				jasmineEnv.execute();
			};

		})();
	</script>

</head>
<body>

	<script type="text/javascript">
		(function(){

			var
				uncurrying = function(fn){
					return function(){
						return Function.prototype.call.apply(fn, arguments);
					}
				},

				slice = uncurrying(Array.prototype.slice),

				fnBindReady = undefined === document.createElement("script").onload ?
					function(elem, fLoaded, scope){
						var
							fPreLoaded = "function" === typeof elem.onreadystatechange ?
							elem.onreadystatechange :
							false
						;

						if("function" === typeof fLoaded){
							elem.onreadystatechange = function(){
								if("loaded" === elem.readyState || "complete" === elem.readyState){
									if(fPreLoaded){
										fPreLoaded.call(scope);

										// gc
										fPreLoaded = null;
									}
									fLoaded.call(scope);

									// gc
									elem.onreadystatechange = null;
									scope = elem = fLoaded = null;
								}
							};
						}
					} :

					function(elem, fLoaded, scope){
						var
							fPreLoaded = "function" === typeof elem.onload ?
							elem.onload :
							false
						;

						if("function" === typeof fLoaded){
							elem.onload = function(){
								if(fPreLoaded){
									fPreLoaded.call(scope);

									//gc
									fPreLoaded = null;
								}
								fLoaded.call(scope);

								// gc
								elem.onload = null;
								scope = elem = fLoaded = null;
							};
						}
					}
			;

			describe("define", function(){
				var iframeEl;

				beforeEach(function(){
					iframeEl = document.createElement("iframe");
					iframeEl.style.width = "1px";
					iframeEl.style.height = "1px";
					iframeEl.style.overflow = "hidden";
					iframeEl.style.border = "none";
				});

				it("双层引自一层", function(){
					var getA, getB;

					runs(function(){

						iframeEl.setAttribute("data-name","双层引自一层");
						fnBindReady(iframeEl, function(){
							var
								w = this.contentWindow,
								jsEl
							;

							jsEl = w.document.createElement("script");

							fnBindReady(jsEl, function(){
								w.require(["./src/define_basic/a-master", "./src/define_basic/b-master"], function(a, b){
									getA = a;
									getB = b;
								});
							});

							jsEl.src = "../../dances.amd.js";
							w.document.getElementsByTagName("head")[0].appendChild(jsEl);

						}, iframeEl);

						document.body.appendChild(iframeEl);

					});

					waitsFor(function(){
						return getA  && getB;
					}, "双层引自一层 fail", 550);

					runs(function(){
						expect(getA.a1).toEqual("a1.js loaded");
						expect(getA.a2).toEqual("a2.js loaded");
						expect(getB.b1).toEqual("b1.js loaded");
						expect(getB.b2).toEqual("b2.js loaded");
					});

				});

				it("5层 define", function(){

					var
						getI
					;

					runs(function(){

						iframeEl.setAttribute("data-name","5层 define");
						fnBindReady(iframeEl, function(){
							var
								w = this.contentWindow,
								jsEl
							;

							jsEl = w.document.createElement("script");

							fnBindReady(jsEl, function(){
								w.require(["./src/define_depthMore/a-master"], function(inst){
									getI = inst;
								});
							});

							jsEl.src = "../../dances.amd.js";
							w.document.getElementsByTagName("head")[0].appendChild(jsEl);

						}, iframeEl);

						document.body.appendChild(iframeEl);

					});

					waitsFor(function(){
						return getI;
					}, "5层 define fail", 1550);

					runs(function(){
						function plusDepth(len){
							var v = 0;

							while(len){
								v += len--;
							}

							return v;
						}

						expect(getI).toEqual(plusDepth(5));
					});

				});

				it("paramDependencies", function(){
					var getA, getB;

					runs(function(){

						iframeEl.setAttribute("data-name","paramDependencies");
						fnBindReady(iframeEl, function(){
							var
								w = this.contentWindow,
								jsEl = w.document.createElement("script")
							;

							fnBindReady(jsEl, function(){
								w.require(["./src/define_paramDependencies/a-master", "./src/define_paramDependencies/b-master"], function(a, b){
									getA = a;
									getB = b;
								});
							});

							jsEl.src = "../../dances.amd.js";
							w.document.getElementsByTagName("head")[0].appendChild(jsEl);

						}, iframeEl);

						document.body.appendChild(iframeEl);

					});

					waitsFor(function(){
						return getA  && getB;
					}, "双层引自一层 fail", 550);

					runs(function(){
						expect(getA.a1).toEqual("a1.js loaded");
						expect(getA.a2).toEqual("a2.js loaded");
						expect(getB.b1).toEqual("b1.js loaded");
						expect(getB.b2).toEqual("b2.js loaded");
					});

				});

				it("multiple require", function(){
					var
						getA,
						getB,
						getC
					;

					runs(function(){

						iframeEl.setAttribute("data-name","multiple require");
						fnBindReady(iframeEl, function(){
							var
								w = this.contentWindow,
								jsEl
							;

							jsEl = w.document.createElement("script");

							fnBindReady(jsEl, function(){
								w.require(["./src/mul_require/a1", "./src/mul_require/~a1", "./src/mul_require/~~a1"], function(a, $a, $$a){
									getA = slice(arguments, 0);
								});

								w.require(["./src/mul_require/b1", "./src/mul_require/~b1"], function(){
									getB = slice(arguments, 0);
								});

								w.require(["./src/mul_require/c1"], function(res){
									getC = res;
								});
							});

							jsEl.src = "../../dances.amd.js";
							w.document.getElementsByTagName("head")[0].appendChild(jsEl);

						}, iframeEl);

						document.body.appendChild(iframeEl);

					});

					waitsFor(function(){
						return getA  && getB && getC;
					}, "multiple require", 550);

					runs(function(){
						expect(getA).toEqual([10, 15, 20]);
						expect(getB.shift().b()).toEqual("b2 created");
						expect(getB.shift().arr.length).toEqual(100);
						expect(getC.c1()).toEqual("created by c1.js");
						expect(getC.c2.main).toEqual("create by c3.js");
						expect(getC.c2.sub).toEqual("create by c3.1.js");
					});

				});

				it("defineParamModOne", function(){
					var
						getA,
						getB,
						getC
					;

					runs(function(){

						iframeEl.setAttribute("data-name","defineParamModOne");
						fnBindReady(iframeEl, function(){
							var
								w = this.contentWindow,
								jsEl
							;

							jsEl = w.document.createElement("script");

							fnBindReady(jsEl, function(){
								w.require(["src/defineParamModOne/a-master"], function(v){
									getA = v;
								});

								w.require(["src/defineParamModOne/a-master-branch"], function(v){
									getB = v;
								});

								w.require(["src/defineParamModOne/a1"], function(v){
									getC = v;
								});
							});

							jsEl.src = "../../dances.amd.js";
							w.document.getElementsByTagName("head")[0].appendChild(jsEl);

						}, iframeEl);

						document.body.appendChild(iframeEl);

					});

					waitsFor(function(){
						return getA && getB && getC;
					}, "defineParamModOne fail", 550);

					runs(function(){
						expect(getA.hasOwnProperty("a-master")).toEqual(true);
						expect(getA["a-master"]).toEqual("a data belong a-master");
						expect(getA["a-master-a1"]).toEqual("a data belong a-a1_____ a message form a2.js");

						expect(getB.hasOwnProperty("a-master-branch")).toEqual(true);
						expect(getB["a-master-a1"]).toEqual("a data belong a-a1_____ a message form a2.js");
						expect(getB["a-x"]).toEqual("fiv");
					})

				});

				it("defineParamModTwo", function(){
					var
						getA,
						getB
					;

					runs(function(){

						iframeEl.setAttribute("data-name","defineParamModTwo");
						fnBindReady(iframeEl, function(){
							var
								w = this.contentWindow,
								jsEl
							;

							jsEl = w.document.createElement("script");

							fnBindReady(jsEl, function(){
								w.require(["src/defineParamModTwo/a-master"], function(v){
									getA = v;
								});

								w.require(["src/defineParamModTwo/a-master-branch"], function(v){
									getB = v;
								});

							});

							jsEl.src = "../../dances.amd.js";
							w.document.getElementsByTagName("head")[0].appendChild(jsEl);

						}, iframeEl);

						document.body.appendChild(iframeEl);

					});

					waitsFor(function(){
						return getA && getB;
					}, "defineParamModTwo fail", 550);

					runs(function(){
						expect(getA.hasOwnProperty("a-master")).toEqual(true);
						expect(getA["a-master-a1"]).toEqual("a data belong a-a1_____ a message form a2.js");

						expect(getB.hasOwnProperty("a-master-branch")).toEqual(true);
						expect(getB["a-master-a1"]).toEqual("a data belong a-a1_____ a message form a2.js");
						expect(getB["a-x"]).toEqual("fiv");
					});

				});

				it("defineID", function(){
					var
						getA
					;

					runs(function(){

						iframeEl.setAttribute("data-name", "defineID");
						fnBindReady(iframeEl, function(){
							var
								w = this.contentWindow,
								jsEl
							;

							jsEl = w.document.createElement("script");

							fnBindReady(jsEl, function(){
								w.require(["src/defineID/define"], function(_){
									w.require(["x-man"], function(_){
										getA = _;
									})
								})
							});

							jsEl.src = "../../dances.amd.js";
							w.document.getElementsByTagName("head")[0].appendChild(jsEl);

						}, iframeEl);

						document.body.appendChild(iframeEl);

					});

					waitsFor(function(){
						return getA;
					}, "defineID fail", 550);

					runs(function(){
						expect(typeof getA.chat).toEqual("function");
						expect(getA.chat()).toEqual("base is loaded");
					});

				});
			});

			describe("require", function(){
				var iframeEl;

				beforeEach(function(){
					iframeEl = document.createElement("iframe");
					iframeEl.style.width = "1px";
					iframeEl.style.height = "1px";
					iframeEl.style.overflow = "hidden";
					iframeEl.style.border = "none";
				});

				it("require invokeII",function(){
					var
						getA
					;

					runs(function(){

						iframeEl.setAttribute("data-name", "require invokeII");
						fnBindReady(iframeEl, function(){
							var
								w = this.contentWindow,
								jsEl
							;

							jsEl = w.document.createElement("script");

							fnBindReady(jsEl, function(){
								w.require(function(_){
									getA = _("src/require_invokeII/a");
								});
							});

							jsEl.src = "../../dances.amd.js";
							w.document.getElementsByTagName("head")[0].appendChild(jsEl);

						}, iframeEl);

						document.body.appendChild(iframeEl);

					});

					waitsFor(function(){
						return getA
					}, "require invokeII fail", 500);

					runs(function(){
						expect(getA).toEqual("ok fine with it");
					});


				});

			});

			describe("conf", function() {
				var iframeEl;

				beforeEach(function(){
					iframeEl = document.createElement("iframe");
					iframeEl.style.width = "1px";
					iframeEl.style.height = "1px";
					iframeEl.style.overflow = "hidden";
					iframeEl.style.border = "none";
				});

				it("baseUrl", function(){
					var getA;

					runs(function(){

						iframeEl.setAttribute("data-name", "baseUrl");
						fnBindReady(iframeEl, function(){
							var
								w = this.contentWindow,
								jsEl
							;

							jsEl = w.document.createElement("script");

							fnBindReady(jsEl, function(){
								w.require.conf({
									"baseUrl": "src/conf/"
								});
								w.require(["baseURl"], function(_){
									getA = _;
								});
							});

							jsEl.src = "../../dances.amd.js";
							w.document.getElementsByTagName("head")[0].appendChild(jsEl);

						}, iframeEl);

						document.body.appendChild(iframeEl);

					});

					waitsFor(function(){
						return getA;
					}, "baseURl fail", 555);

					runs(function(){
						require.conf("baseUrl", "");
						expect(getA).toEqual("you get me.");
					});

				});

				it("paths", function(){
					var
						getA,
						getB,
						iWin
					;

					runs(function(){

						iframeEl.setAttribute("data-name", "paths");
						fnBindReady(iframeEl, function(){
							var
								w = this.contentWindow,
								jsEl
							;

							iWin = w;
							jsEl = w.document.createElement("script");

							fnBindReady(jsEl, function(){
								w.define.amd.jQuery = true;

								w.require
									.conf("paths", {
										jq: "src/conf/jquery-1.7.2.min.js",
										us: "src/conf/underscore-min.js"
									})
									.conf("shim", {
										us: {
											exports: "_"
										}
									})
								;

								w.require(["jq", "us"], function($, _){
									getA = $("body");
									getB = _.toArray(getA)[0];
								});
							});

							jsEl.src = "../../dances.amd.js";
							w.document.getElementsByTagName("head")[0].appendChild(jsEl);

						}, iframeEl);

						document.body.appendChild(iframeEl);

					});

					waitsFor(function(){
						return getA && getB;
					}, "path fail", 550);

					runs(function(){
						expect(getA[0] === iWin.document.body).toEqual(true);
						expect(getB === iWin.document.body).toEqual(true);
					});

				});

				it("timeout", function(){
					var
						getA
					;

					runs(function(){

						iframeEl.setAttribute("data-name", "paths");
						fnBindReady(iframeEl, function(){
							var
								w = this.contentWindow,
								jsEl
							;

							jsEl = w.document.createElement("script");

							fnBindReady(jsEl, function(){

								w.require
									.conf("timeout", 1)
								;

								w.require(["src/timeout/a"], function(_){
									getA = _;
								})
									.error(function(){
										getA = slice(arguments)
									})
								;
							});

							jsEl.src = "../../dances.amd.js";
							w.document.getElementsByTagName("head")[0].appendChild(jsEl);

						}, iframeEl);

						document.body.appendChild(iframeEl);

					});

					waitsFor(function(){
						return getA;
					}, "timeout fail", 500);

					runs(function(){

						expect(getA[0]).toEqual("timeout");

					});

				});

			});

			describe("fix bugs in 2.0", function(){
				var iframeEl;

				beforeEach(function(){
					iframeEl = document.createElement("iframe");
					iframeEl.style.width = "1px";
					iframeEl.style.height = "1px";
					iframeEl.style.overflow = "hidden";
					iframeEl.style.border = "none";
				});

				it("call factory the same", function(){

					var
						getA,
						getB,
						iWin
					;

					runs(function(){

						iframeEl.setAttribute("data-name", "call factory the same");
						fnBindReady(iframeEl, function(){
							var
								w = this.contentWindow,
								jsEl
							;

							iWin = w;

							jsEl = w.document.createElement("script");

							fnBindReady(jsEl, function(){
								w.require(["./src/mul_require_sameFile/a"], function(_){
									getA = _;
								});

								w.require(["./src/mul_require_sameFile/a"], function(_){
									getB = _;
								});
							});

							jsEl.src = "../../dances.amd.js";
							w.document.getElementsByTagName("head")[0].appendChild(jsEl);

						}, iframeEl);

						document.body.appendChild(iframeEl);

					});

					waitsFor(function(){
						return getA && getB;
					}, "call factory the same", 550);

					runs(function(){
						expect(getA.reflect("first")).toEqual("first");
						expect(getB.reflect("second")).toEqual("second");
						expect(getA.reflect === getB.reflect).toEqual(true);

						expect(iWin.dances.add.__view()["./src/mul_require_sameFile/a"].__TEST_CALL_THE_SAME).toEqual(1);

					});


				});

				it("call mix", function(){
					var
						getA,
						getB,
						getC,
						getD
					;

					runs(function(){

						iframeEl.setAttribute("data-name", "call mix");
						fnBindReady(iframeEl, function(){
							var
								w = this.contentWindow,
								jsEl
							;

							jsEl = w.document.createElement("script");

							fnBindReady(jsEl, function(){
								w.require(["./src/mul_require_mix/mod1"], function($){
									getA = $;
								});

								w.require(["./src/mul_require_mix/mod2", "./src/mul_require_mix/mod1"], function($1, $2){
									getB = $1;
								});

								w.require(["./src/mul_require_mix/mod2", "./src/mul_require_mix/mod3"], function($1, $2){
									getC = $2;
								});

								w.require(["./src/mul_require_mix/mod3", "./src/mul_require_mix/mod1"], function($1, $2){
									getD = $2;
								});
							});

							jsEl.src = "../../dances.amd.js";
							w.document.getElementsByTagName("head")[0].appendChild(jsEl);

						}, iframeEl);

						document.body.appendChild(iframeEl);

					});

					waitsFor(function(){
						return getA && getB && getC && getD;
					}, "call fix", 550);

					runs(function(){
						expect(getA.name).toEqual("mod1");
						expect(getB.name).toEqual("mod2");
						expect(getC.name).toEqual("mod3");
						expect(getD.name).toEqual("mod1");
					});

				});
			});

			describe("shim", function(){

				var iframeEl;

				beforeEach(function(){
					iframeEl = document.createElement("iframe");
					iframeEl.style.width = "1px";
					iframeEl.style.height = "1px";
					iframeEl.style.overflow = "hidden";
					iframeEl.style.border = "none";
				});

				it("自定模块 dances.color", function(){
					var
						getA
					;

					runs(function(){

						iframeEl.setAttribute("data-name", "自定模块 dances.color");
						fnBindReady(iframeEl, function(){
							var
								w = this.contentWindow,
								jsEl
							;

							jsEl = w.document.createElement("script");

							fnBindReady(jsEl, function(){
								w.require.conf({
									shim: {
										color: {
											path   : "src/conf/dances.color.js",
											exports: "dances.color"
										}
									}
								});

								w.require(["color"], function(color){
									getA = color("#fffff");
								});
							});

							jsEl.src = "../../dances.amd.js";
							w.document.getElementsByTagName("head")[0].appendChild(jsEl);

						}, iframeEl);

						document.body.appendChild(iframeEl);

					});

					waitsFor(function(){
						return getA;
					}, "shim 自定模块 dances.color", 550);

					runs(function(){
						expect(getA).toEqual("#fffff");
					});

				});

				it("jquery_1.4", function(){
					var
						getA
					;

					runs(function(){

						iframeEl.setAttribute("data-name", "jquery_1.4");
						fnBindReady(iframeEl, function(){
							var
								w = this.contentWindow,
								jsEl
							;

							jsEl = w.document.createElement("script");

							fnBindReady(jsEl, function(){
								w.require.conf({
									shim: {
										$14: {
											path   : "src/shim/jquery-1.4.4.min",
											exports: "jQuery"
										}
									}
								});

								w.require(["$14"], function($){
									getA = $;
								});
							});

							jsEl.src = "../../dances.amd.js";
							w.document.getElementsByTagName("head")[0].appendChild(jsEl);

						}, iframeEl);

						document.body.appendChild(iframeEl);

					});

					waitsFor(function(){
						return getA
					}, "shim jquery_14 fail", 500);

					runs(function(){
						expect(getA().jquery ).toEqual("1.4.4");
					});

				});


				it("测试错误添加 非AMD 模块", function(){
					var
						getA
					;

					runs(function(){
						iframeEl.setAttribute("data-name", "测试错误添加 非AMD 模块");
						fnBindReady(iframeEl, function(){
							var
								w = this.contentWindow,
								jsEl
							;

							jsEl = w.document.createElement("script");

							fnBindReady(jsEl, function(){
								w.require.conf("timeout", 500);

								w.require(["src/shim/noAMD"], function(_){
									getA = _;
								})
									.error(function(status, inst){
										getA = slice(arguments);
									})

								;
							});

							jsEl.src = "../../dances.amd.js";
							w.document.getElementsByTagName("head")[0].appendChild(jsEl);

						}, iframeEl);

						document.body.appendChild(iframeEl);

					});

					waitsFor(function(){
						return getA;
					}, "测试错误添加 非AMD 模块 fail", 500);

					runs(function(){
						expect(getA[0]).toEqual("noAMD");
						expect(getA[1].exports).toEqual(undefined);
						expect(getA[1].src).toEqual("src/shim/noAMD.js");
					});

				});

			});

			describe("miscellaneous", function(){
				var iframeEl;

				beforeEach(function(){
					iframeEl = document.createElement("iframe");
					iframeEl.style.width = "1px";
					iframeEl.style.height = "1px";
					iframeEl.style.overflow = "hidden";
					iframeEl.style.border = "none";
				});

				it("恶意调用 define", function(){
				});
			});

			execJasmine();

		})();
	</script>

</body>
</html>